package com.niiwoo.civet.trade.report.client.report;


import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.niiwoo.asset.org.business.dto.request.OrgApplyOrderRequestDTO;
import com.niiwoo.asset.org.business.dto.response.OrgApplyOrderInfoRespDTO;
import com.niiwoo.asset.org.business.service.dubbo.OrgProjectOrderDubboService;
import com.niiwoo.civet.account.BillBaseDubboService;
import com.niiwoo.civet.account.dto.request.BillDailySheetRequestDTO;
import com.niiwoo.civet.account.dto.response.AccountCompanyDTO;
import com.niiwoo.civet.account.dto.response.BillDailySheetResponseDTO;
import com.niiwoo.civet.account.service.AccountCompanyDubboService;
import com.niiwoo.civet.base.enums.ChannelCodeEnum;
import com.niiwoo.civet.base.enums.DeadlineUnitEnum;
import com.niiwoo.civet.base.enums.FeeTypeEnum;
import com.niiwoo.civet.trade.dao.entity.*;
import com.niiwoo.civet.trade.dao.mapper.*;
import com.niiwoo.civet.trade.dto.response.org.AssetOrgProjectResponseDTO;
import com.niiwoo.civet.trade.enums.*;
import com.niiwoo.civet.trade.property.RtsBaseProperties;
import com.niiwoo.civet.trade.report.CompanyTradeEnum;
import com.niiwoo.civet.trade.report.client.report.p2p.d.*;
import com.niiwoo.civet.trade.report.dto.ProjectInvestOrderExt;
import com.niiwoo.civet.trade.report.upload.ReportProjectDescUtil;
import com.niiwoo.civet.trade.service.local.org.OrgProjectLocalService;
import com.niiwoo.civet.trade.utils.RepaymentUtil;
import com.niiwoo.civet.user.dto.UserProfessionDubboInfoDTO;
import com.niiwoo.civet.user.dto.request.SimpleOrgInfo;
import com.niiwoo.civet.user.service.OrganizationDubboService;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserDataDubboService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.base.utils.DateUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.*;

/**
 * @version 20180906
 * www.resoft.css.com.cn
 * 日报数据获取
 * @author wanglei
 *
 */
@Service
@Slf4j
@EnableConfigurationProperties(RtsBaseProperties.class)
public class DateReportDataService {
	private final Integer pageSize = 500;//每页标的个数
	@Autowired
	private ProjectMapperExt projectMapperExt;
	@Autowired
	private ProjectInvestOrderMapperExt projectInvestOrderMapperExt;
	@Autowired
	private RtsBaseProperties rtsBaseProperties;
	@Value("${h5-niiwoo-project-detail-url}")
	private String h5BorrowDetailUrl;
	@Autowired
	private OrgProjectLocalService orgProjectLocalService;
	@Reference(version = "1.0.0")
	private UserBasicInfoDubboService userBasicInfoDubboService;
	@Reference(version = "1.0.0")
	private UserDataDubboService userDataDubboService;
	@Reference(version = "1.0.0")
	private OrganizationDubboService organizationDubboService;
	@Reference(version = "1.0.0")
	private OrgProjectOrderDubboService orgProjectOrderDubboService;
	@Autowired
	private PrivacyMasks privacyMasks;
	@Autowired
	private ProjectBorrowerPlanDetailMapperExt projectBorrowerPlanDetailMapperExt;
	@Autowired
	private ProjectBorrowerPlanNewMapperExt projectBorrowerPlanNewMapperExt;
	@Autowired
	private ProjectInvestorPlanMapperExt projectInvestorPlanMapperExt;
	@Autowired
	private RefundOrderMapperExt refundOrderMapperExt;
	@Autowired
	private ProjectGuaranteePlanMapperExt projectGuaranteePlanMapperExt;
	@Reference(version = "1.0.0")
	private AccountCompanyDubboService accountCompanyDubboService;
	@Reference(version = "1.0.0",timeout = 10*60*1000)
	private BillBaseDubboService billBaseDubboService;
	@Autowired
	private CreditorSaleDetailMapperExt creditorSaleDetailMapperExt;
	@Autowired
	private ProjectPenaltyChangeRecordMapper projectPenaltyChangeRecordMapper;


	@Data
	public static class ParamsDate{
		private Date startDate;
		private Date endDate;
	}

	/**
	 * 项目信息
	 * @param reportDateStr yyyyDDmm
	 * @return
	 */
	public  List<J1001> getJ1001Data(String reportDateStr){
		ParamsDate paramsDate = this.getParamsDate(reportDateStr);

		Map<String,Object> countMap = this.getCountMap(reportDateStr,paramsDate) ;
		log.info("查询标的信息，getJ1001Data，countMap={}", JSON.toJSONString(countMap));
		int countNum = new Integer(countMap.get("countNum").toString());
		List<J1001> rowDataLists = new ArrayList<>();
		if ( countNum > 0 ){
			int totalPage = countNum % pageSize == 0? countNum/pageSize : countNum/pageSize+1;
			log.info("统计总标的数{}，总页面数{}",countNum,totalPage);
			for (int currentPage = 1;currentPage <= totalPage ; currentPage++){
				int startIndex = currentPage>1?  pageSize * (currentPage-1):0;
				List<Project> projectList = this.getProjectList(reportDateStr,paramsDate,startIndex,pageSize);
//				if (currentPage == 1){
//					//如标的费用有减免，需要重新上报标的信息
//					List<ProjectPenaltyChangeRecord>  list = projectPenaltyChangeRecordMapper.listByTimeChangeServiceFee(paramsDate.getStartDate(),paramsDate.getEndDate());
//					Set<Long> setProjectIds = new HashSet<>();
//					list.forEach(p->setProjectIds.add(p.getProjectId()));
//					List<Project> projectsForChange = projectMapperExt.queryProjectListByProjectIds(new ArrayList<>(setProjectIds));
//					log.info("当天减免服务费标的={}",JSON.toJSONString(setProjectIds));
//					projectList.addAll(projectsForChange);//当天放款，当天不可能减免服务费，无需去重
//				}
				for (Project project : projectList) {
					if (project.getChannelCode().equals(ChannelCodeEnum.KAOLA.getChanelCode())){
						continue;
					}
					J1001 rowData = new J1001();
					rowData.setJ1001001(project.getProjectId().toString());
					rowData.setJ1001002(ReportProjectDescUtil.getProjectTypeDescByLoadType(LoanTypeEnum.enumOf(project.getLoanType())));
					rowData.setJ1001003(project.getContractAmount().toString());
					rowData.setJ1001004(DateUtils.format(project.getPublishTime(),DateUtils.SHOW_DATETIME_FORMAT));
					rowData.setJ1001005(h5BorrowDetailUrl+project.getProjectId());
					Date projectEndDate = projectBorrowerPlanNewMapperExt.selectLastRefundDayByProjectId(project.getProjectId());
					if (projectEndDate == null){
						log.info("projectEndDate为空，标的异常{},",project.getProjectId());
						continue;
					}
					BigDecimal numberForYear = null;//年数
					if (project.getDeadlineUnit().equals(DeadlineUnitEnum.BY_MONTH.getDeadlineUnit())){//单位 月
						numberForYear = new BigDecimal(project.getDeadline()).divide(new BigDecimal(12), MathContext.DECIMAL128);
					}else {//单位 天
						numberForYear = new BigDecimal(project.getDeadline()).divide(new BigDecimal(365), MathContext.DECIMAL128);
					}
					Integer daysNum = RepaymentUtil.getOverdueDay(project.getFullSuccessTime(),projectEndDate);
					rowData.setJ1001006(daysNum.toString());

					List<ProjectInvestOrder> projectInvestOrderList = projectInvestOrderMapperExt.selectInvestedList(project.getProjectId());
					BigDecimal allInterest = new BigDecimal("0.00");
					for (ProjectInvestOrder order : projectInvestOrderList) {
						if (!order.getInvestType().equals(Byte.valueOf("2"))) {//投资类型：1-原始标，2-债转标，3-智能投 统计不为债转标的利息
							allInterest = allInterest.add(order.getInterest());
						}
					}

					BigDecimal borrowerTotalFee = project.getManageFee().add(project.getGuaranteeFee())
							                                            .add(project.getConsultingFee())
							                                            .add(allInterest)
																		.add(project.getBeforeManageFee()==null? new BigDecimal("0.00"):project.getBeforeManageFee())
																		.add(project.getBeforeSeekAdviceServiceFee());
					BigDecimal allBorrowerRate = borrowerTotalFee.divide(project.getContractAmount(),MathContext.DECIMAL128)
															     .divide(numberForYear,4,BigDecimal.ROUND_HALF_EVEN);
					log.info("标的年化综合利率,projectId={},allBorrowerRate={}",project.getProjectId(),allBorrowerRate);

					rowData.setJ1001007(allBorrowerRate.multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_DOWN).toString());
					rowData.setJ1001008(DateUtils.format(project.getFullSuccessTime(),DateUtils.SHOW_DATE_FORMAT));
					rowData.setJ1001009(getRepaymentForJrb(project));
					rowData.setJ1001010("3");
					String loanUsage = project.getTitle().trim().replaceAll("借款用于", "").replaceAll("借款用途：","");
					rowData.setJ1001011(loanUsage);
					String incomeSource = "";
					AssetOrgProjectResponseDTO assetOrgProjectResponseDTO = orgProjectLocalService.getAsserOrgProject(project.getProjectId());
					if (assetOrgProjectResponseDTO == null){
						try {
							UserProfessionDubboInfoDTO userProfessionDubboInfoDTO = userDataDubboService.userProfessionInfo(project.getBorrowUserId());
							//收入来源：0-未知，1-工资劳务报酬，2-兼职收入，3-其他收入
							Byte sourceOfIncome = userProfessionDubboInfoDTO.getSourceOfIncome();
							if (sourceOfIncome.equals(Byte.valueOf("0"))){
								incomeSource = "其他收入";//前端APP把未知显示成其它收入
							}else if (sourceOfIncome.equals(Byte.valueOf("1"))){
								incomeSource = "工资劳务报酬";
							}else if (sourceOfIncome.equals(Byte.valueOf("2"))){
								incomeSource = "兼职收入";
							}else if (sourceOfIncome.equals(Byte.valueOf("3"))){
								incomeSource = "其他收入";
							}
						}catch (Exception e){
							log.info("userDataDubboService服务不可用",e);
							incomeSource = "其他收入";
						}
					} else {
						OrgApplyOrderRequestDTO orgApplyOrderRequestDTO = new OrgApplyOrderRequestDTO();
						orgApplyOrderRequestDTO.setOrderId(assetOrgProjectResponseDTO.getOrderId());
						OrgApplyOrderInfoRespDTO orderInfoRespDTO;
						try {
							orderInfoRespDTO = orgProjectOrderDubboService.queryOrgApplyReletInfo(orgApplyOrderRequestDTO);
							incomeSource = orderInfoRespDTO.getRepaymentSource();
						}catch (Exception e){
							log.info("资产服务不可用",e);
							incomeSource = "其他收入";
						}
					}
					rowData.setJ1001012(incomeSource);
					rowData.setJ1001013("融资人借款用途合法合规；融资人信用状况良好；个人收入作为第一还款来源；第三方担保");//借款人风险评测
					rowDataLists.add(rowData);
				}
			}
		}
		log.info("getJ1001Data.rowDate.size={}",rowDataLists.size());
		return rowDataLists;
	}
	/**
	 * 借款人信息
	 * @param reportDateStr
	 * @return
	 */
	public  List<J1002> getJ1002Data(String reportDateStr){

		ParamsDate paramsDate = this.getParamsDate(reportDateStr);
		//当天满标的
		Map<String,Object> countMap = this.getCountMap(reportDateStr,paramsDate) ;
		log.info("查询标的信息，getJ1002Data，countMap={}", JSON.toJSONString(countMap));
		int countNum = new Integer(countMap.get("countNum").toString());
		List<J1002> rowDataLists = new ArrayList<>();
		Set<Long> projectIdSets = new HashSet<>();
		if ( countNum > 0 ){
			int totalPage = countNum % pageSize == 0? countNum/pageSize : countNum/pageSize+1;
			log.info("统计总标的数{}，总页面数{}",countNum,totalPage);
			for (int currentPage = 1;currentPage <= totalPage ; currentPage++){
				int startIndex = currentPage>1?  pageSize * (currentPage-1):0;
				List<Project> projectList = this.getProjectList(reportDateStr,paramsDate,startIndex,pageSize);
				for (Project project : projectList) {
					projectIdSets.add(project.getProjectId());
				}
				this.buildDateJ10002(projectList,rowDataLists,reportDateStr);
			}
		}
		//当天有还款的
		this.buildDateJ10002(this.getProjectHaveRefunded(reportDateStr,projectIdSets),rowDataLists,reportDateStr);
		log.info("getJ1002Data.rowDate.size={}",rowDataLists.size());
		return rowDataLists;
	}

	/**
	 * 投资人信息
	 * 包含三部分：当天放款的标的，当天有还款的标的，当天有债权转让的标的
	 * @return
	 */
	public  List<J1003> getJ1003Data(String reportDateStr){

		ParamsDate paramsDate = this.getParamsDate(reportDateStr);

		//当天满标的
		Map<String,Object> countMap = this.getCountMap(reportDateStr,paramsDate) ;
		log.info("查询标的信息，getJ1003Data，countMap={}", JSON.toJSONString(countMap));
		int countNum = new Integer(countMap.get("countNum").toString());
		List<J1003> rowDataLists = new ArrayList<>();
		Set<Long> projectIdSets = new HashSet<>();
		if ( countNum > 0 ){
			int totalPage = countNum % pageSize == 0? countNum/pageSize : countNum/pageSize+1;
			log.info("统计总标的数{}，总页面数{}",countNum,totalPage);
			for (int currentPage = 1;currentPage <= totalPage ; currentPage++){
				int startIndex = currentPage>1?  pageSize * (currentPage-1):0;
				List<Project> projectList = this.getProjectList(reportDateStr,paramsDate,startIndex,pageSize);
				for (Project project : projectList) {
					projectIdSets.add(project.getProjectId());
				}
				this.buildDateJ10003(projectList,rowDataLists,reportDateStr);
			}
		}

		//当天有还款的
		this.buildDateJ10003(this.getProjectHaveRefunded(reportDateStr,projectIdSets),rowDataLists,reportDateStr);

		//当天有债转的
		List<Long> projectList = projectInvestOrderMapperExt.selectTransferProjectIdListByTime(paramsDate.getStartDate(),paramsDate.getEndDate());
		projectList.removeAll(projectIdSets);//移除已处理的标的
		if(!projectList.isEmpty()) {
			this.buildDateJ10003(projectMapperExt.selectListByProjectIdSet(projectList), rowDataLists, reportDateStr);
		}
		log.info("getJ1003Data.rowDate.size={}",rowDataLists.size());
		return rowDataLists;
	}

	/**
	 * 担保信息
	 * @return
	 */
	public List<J1004> getJ1004Data(String reportDateStr){
		ParamsDate paramsDate = this.getParamsDate(reportDateStr);
		//当天满标的
		Map<String,Object> countMap = this.getCountMap(reportDateStr,paramsDate) ;
		log.info("查询标的信息，getJ1004Data，countMap={}", JSON.toJSONString(countMap));
		int countNum = new Integer(countMap.get("countNum").toString());
		List<J1004> rowDataLists = new ArrayList<>();
		if ( countNum > 0 ){
			int totalPage = countNum % pageSize == 0? countNum/pageSize : countNum/pageSize+1;
			log.info("统计总标的数{}，总页面数{}",countNum,totalPage);
			for (int currentPage = 1;currentPage <= totalPage ; currentPage++){
				int startIndex = currentPage>1?  pageSize * (currentPage-1):0;
				List<Project> projectList = this.getProjectList(reportDateStr,paramsDate,startIndex,pageSize);
				this.buildDateJ10004(projectList,rowDataLists,reportDateStr);
			}
		}
		//当天有还款的
		this.buildDateJ10004(this.getProjectHaveGuarantee(reportDateStr),rowDataLists,reportDateStr);
		log.info("getJ1004Data.rowDate.size={}",rowDataLists.size());
		return rowDataLists;
	}

	/**
	 * 债权转让信息
	 * @param reportDateStr
	 * @return
	 */
	public List<J1005> getJ1005Data(String reportDateStr){
		ParamsDate paramsDate = this.getParamsDate(reportDateStr);
		Integer countNum = projectInvestOrderMapperExt.countTransferNumByTime(paramsDate.getStartDate(),paramsDate.getEndDate());

		log.info("上报债权转让信息getJ1005Data ，总数={}",countNum);
		List<J1005> rowDataLists = new ArrayList<>();
		if ( countNum > 0 ){
			int totalPage = countNum % pageSize == 0? countNum/pageSize : countNum/pageSize+1;
			log.info("统计总标的数{}，总页面数{}",countNum,totalPage);
			for (int currentPage = 1;currentPage <= totalPage ; currentPage++){
				int startIndex = currentPage>1?  pageSize * (currentPage-1):0;
				List<ProjectInvestOrderExt> projectList = projectInvestOrderMapperExt.selectTransferListByTime(paramsDate.getStartDate(),paramsDate.getEndDate(),startIndex,pageSize);
				for (ProjectInvestOrderExt investOrder : projectList) {
					J1005 j1005 = new J1005();
					CreditorSaleDetail creditorSaleDetail = creditorSaleDetailMapperExt.selectByPrimaryKeyAndSaleUserId(investOrder.getCreditorSaleDetailId(),investOrder.getCreditorSaleUserId());
					if (creditorSaleDetail == null){
						log.info("债转数据不存在,investorOrder={}",JSON.toJSONString(investOrder));
						continue;
					}
					j1005.setJ1005001(investOrder.getCreditorSaleDetailId().toString());
					j1005.setJ1005002(investOrder.getProjectId().toString());
					j1005.setJ1005003(investOrder.getCreditorSaleUserId());
					j1005.setJ1005004(creditorSaleDetail.getPlatformUserNo());
					j1005.setJ1005005(investOrder.getShare().setScale(2,BigDecimal.ROUND_DOWN).toString());
					j1005.setJ1005006(""+(creditorSaleDetail.getRemainingDeadlineDay()+creditorSaleDetail.getRemainingDeadlineMonth()*30));
					j1005.setJ1005007(DateUtils.format(investOrder.getFullSuccessTime(),DateUtils.SHOW_DATE_FORMAT));
					j1005.setJ1005008(investOrder.getAmount().toString());
					j1005.setJ1005009(investOrder.getUserId());
					j1005.setJ1005010(investOrder.getPlatformUserNo());
					rowDataLists.add(j1005);
				}
			}
		}
		return rowDataLists;
	}

	/**
	 * 资金交易信息
	 * @param reportDateStr
	 * @return
	 */
	public List<J1006> getJ1006Data(String reportDateStr){

		List<J1006> rowDataLists = new ArrayList<>();
		BillDailySheetRequestDTO billDailySheetRequestDTO = new BillDailySheetRequestDTO();
		Date date = DateUtils.parseDateFromString(reportDateStr,DateUtils.DATE_FORMAT);
		billDailySheetRequestDTO.setYearMonthDay(DateUtils.format(date,DateUtils.SHOW_DATE_FORMAT));
		List<BillDailySheetResponseDTO> list = billBaseDubboService.getBillDailySheet(billDailySheetRequestDTO);
		J1006 rowData = null;
		log.info("查询账户中心金融办数据,size={}",list.size());
		for (BillDailySheetResponseDTO sheetDTO : list) {
			rowData = new J1006();
			rowData.setJ1006001(sheetDTO.getId().toString());
			rowData.setJ1006002(sheetDTO.getProjectId() == null ? "":sheetDTO.getProjectId().toString());
			rowData.setJ1006003(DateUtils.format(sheetDTO.getTransactionTime(),DateUtils.SHOW_DATETIME_FORMAT));
			rowData.setJ1006004(sheetDTO.getUserId() );
			rowData.setJ1006005(sheetDTO.getUserAccountNo());
			rowData.setJ1006006(sheetDTO.getRemark());
			rowData.setJ1006007(sheetDTO.getAmount().toString());
			rowData.setJ1006008(sheetDTO.getBalanceAmount().toString());
			rowData.setJ1006009(sheetDTO.getRelationUserIds());
			rowData.setJ1006010(sheetDTO.getRelationAccountNos());
			rowDataLists.add(rowData);
		}
		return rowDataLists;
	}



	private String getRepaymentForJrb(Project project){
		if (project.getRepaymentType().equals(RepaymentTypeEnum.REPAY_PRINCIPAL_INTEREST_AT_TERM.getValue())
				&& project.getOrgId().equals("97554301928890368")
				&& project.getDeadlineUnit().equals(DeadlineUnitEnum.BY_DAY.getDeadlineUnit())){
			return "3";//按日计息，一次还本付息
		}else if (project.getRepaymentType().equals(RepaymentTypeEnum.REPAY_PRINCIPAL_INTEREST_AT_TERM.getValue())){
			return "4";//一次还本付息
		}else if (project.getRepaymentType().equals(RepaymentTypeEnum.AVERAGE_CAPITAL_PLUS_INTEREST.getValue())){
			return "1";//等额本息
		}else if (project.getRepaymentType().equals(RepaymentTypeEnum.MONTHLY_INTEREST_PAYMENT_DUE.getValue())){
			return "2";//先息后本
		}else {
			log.info("没有找到对应的还款方式,projectId={}",project.getProjectId());
		}
		return "1";
	}




	private void buildDateJ10002(List<Project> projectList,List<J1002> rowDataLists,String reportDateStr){
		J1002 rowData = null;
		for (Project project : projectList) {
			if (project.getChannelCode().equals(ChannelCodeEnum.KAOLA.getChanelCode())){
				continue;
			}
			rowData = new J1002();
			rowData.setJ1002001(project.getProjectId().toString());
			rowData.setJ1002002(project.getBorrowUserId());
			rowData.setJ1002003(project.getBorrowerType().equals(BorrowerTypeEnum.COMPANY.getType()) ? "1" : "0");//0个人，1企业
			rowData.setJ1002004(project.getBorrowerType().equals(BorrowerTypeEnum.COMPANY.getType()) ? null : project.getBorrowUserName());
			rowData.setJ1002005(project.getBorrowerType().equals(BorrowerTypeEnum.COMPANY.getType()) ? null : "0");//0身份证号
			rowData.setJ1002006(project.getBorrowerType().equals(BorrowerTypeEnum.COMPANY.getType()) ? null : privacyMasks.decryptPrivacy(project.getBorrowIdCard()));
			rowData.setJ1002007(project.getBorrowerType().equals(BorrowerTypeEnum.COMPANY.getType()) ? null : privacyMasks.decryptPrivacy(project.getBorrowMobile()));

			if (project.getBorrowerType().equals(BorrowerTypeEnum.COMPANY.getType())) {
				SimpleOrgInfo simpleOrgInfo = organizationDubboService.getByOrgId(project.getBorrowUserId());
				if (simpleOrgInfo != null) {
					rowData.setJ1002008(simpleOrgInfo.getOrganizationName());
					rowData.setJ1002009(simpleOrgInfo.getUnifiedSocialCreditCode());
					rowData.setJ1002010(privacyMasks.decryptPrivacy(simpleOrgInfo.getLegalPersonCertNumber()));
				}
			}

			UserProfessionDubboInfoDTO userProfessionDubboInfoDTO = userDataDubboService.userProfessionInfo(project.getBorrowUserId());
			if (userProfessionDubboInfoDTO != null) {
				rowData.setJ1002011(CompanyTradeEnum.enumOf(userProfessionDubboInfoDTO.getCompanyTrades()).getTradeDesc());//company_trades
			}else {
				log.info("借款用户信息查询为空{}",project.getBorrowUserId());
				rowData.setJ1002011("未知");
			}
			rowData.setJ1002012(project.getLoanCity());
			BigDecimal toRepayAmount = projectBorrowerPlanDetailMapperExt.countToPayMoneyByProjectIdAndFeeType(project.getProjectId(), FeeTypeEnum.CAPITAL.getValue());
			rowData.setJ1002013(toRepayAmount.toString());

			Date reportDate = DateUtils.parseDateFromString(reportDateStr, DateUtils.DATE_FORMAT);
			Date compareDate = new DateTime(reportDate).minusDays(5).toDate();//逾期大于4天
			//List<ProjectBorrowerPlanNew> projectBorrowerPlanNewList = projectBorrowerPlanNewMapperExt.selectNeedRefundList(project.getProjectId(),compareDate);
			//查得是投资人逾期
			List<ProjectInvestorPlan> projectInvestorPlanList = projectInvestorPlanMapperExt.selectNeedReceiveList(project.getProjectId(), compareDate);//逾期超过4天
			BigDecimal overDueCapital4DaysAmount = new BigDecimal("0.00");
			BigDecimal overDueInterest4DaysAmount = new BigDecimal("0.00");
			Date capitalOverdueDate = null;
			Date interestOverdueDate = null;
			for (ProjectInvestorPlan investorPlan : projectInvestorPlanList) {
				if (investorPlan.getCapital().subtract(investorPlan.getReceivedCapital()).compareTo(BigDecimal.ZERO) > 0
						&& (capitalOverdueDate == null || investorPlan.getReceivedDate().before(capitalOverdueDate))) {
					capitalOverdueDate = investorPlan.getReceivedDate();
				}

				if (investorPlan.getInterest().subtract(investorPlan.getReceivedInterest()).compareTo(BigDecimal.ZERO) > 0
						&& (interestOverdueDate == null || investorPlan.getReceivedDate().before(interestOverdueDate))) {
					interestOverdueDate = investorPlan.getReceivedDate();
				}
				overDueCapital4DaysAmount = overDueCapital4DaysAmount.add(investorPlan.getCapital().subtract(investorPlan.getReceivedCapital()));
				overDueInterest4DaysAmount = overDueInterest4DaysAmount.add(investorPlan.getInterest().subtract(investorPlan.getReceivedInterest()));

			}
			if (capitalOverdueDate == null){
				rowData.setJ1002014("0000-00-00");//本金yu期日期
			}else {
				rowData.setJ1002014(DateUtils.format(capitalOverdueDate, DateUtils.SHOW_DATE_FORMAT));//本金逾期日期
			}
			rowData.setJ1002015(overDueCapital4DaysAmount.toString());//本金逾期金额
			if (interestOverdueDate == null){
				rowData.setJ1002016("0000-00-00");//利息逾期日期
			}else {
				rowData.setJ1002016(DateUtils.format(interestOverdueDate, DateUtils.SHOW_DATE_FORMAT));//利息逾期日期
			}
			rowData.setJ1002017(overDueInterest4DaysAmount.toString());//利息逾期金额
			rowData.setJ1002018(project.getBorrowPlatformUserNo());//平台存管账户号
			rowDataLists.add(rowData);
		}
	}

	/**
	 * 查询日报当天有还款标的
	 * @param reportDateStr
	 * @return
	 */
	private List<Project> getProjectHaveRefunded(String reportDateStr,Set<Long> setIds){
		Date startDate = DateUtils.parseDateFromString(reportDateStr,DateUtils.DATE_FORMAT);
		Date endDate = new DateTime(startDate).plusDays(1).toDate();
        if (startDate.before(DateUtils.parseDateFromString("20181028",DateUtils.DATE_FORMAT))){
            return new ArrayList<>();
        }

        List<RefundOrder> refundOrderList = refundOrderMapperExt.listSuccessOrdersByDate(startDate,endDate);

		Set<Long> setProjectIds = new HashSet<>();
		for (RefundOrder order : refundOrderList) {
			setProjectIds.add(order.getProjectId());
		}
		if (setProjectIds.size()>0){
			log.info("查询日报当天有还款标的{}，size={} ",JSON.toJSONString(setProjectIds),setProjectIds.size());
			setProjectIds.removeAll(setIds);
			log.info("查询日报当天有还款标的{}，size={} ",JSON.toJSONString(setProjectIds),setProjectIds.size());
			if (!CollectionUtils.isEmpty(setProjectIds)){
				setIds.addAll(setProjectIds);
				return projectMapperExt.selectListByProjectIdSet(new ArrayList<>(setProjectIds));
			}
		}
		return new ArrayList<>();
	}

	/**
	 * 查询日报当天有还款标的
	 * @param reportDateStr
	 * @return
	 */
	private List<Project> getProjectHaveGuarantee(String reportDateStr){
		Date startDate = DateUtils.parseDateFromString(reportDateStr,DateUtils.DATE_FORMAT);
		Date endDate = new DateTime(startDate).plusDays(1).toDate();
        if (startDate.before(DateUtils.parseDateFromString("20181028",DateUtils.DATE_FORMAT))){
            return new ArrayList<>();
        }
		List<RefundOrder> refundOrderList = refundOrderMapperExt.listSuccessOrdersByDate(startDate,endDate);

		Set<Long> setProjectIds = new HashSet<>();
		for (RefundOrder order : refundOrderList) {
			if (order.getTradeType().equals(RefundTradeTypeEnum.ADVANCE.getTradeType())){
				setProjectIds.add(order.getProjectId());
			}
		}
		if (setProjectIds.size()>0){
			log.info("查询日报当天有垫付标的{}",JSON.toJSONString(setProjectIds));
			return projectMapperExt.selectListByProjectIdSet(new ArrayList<>(setProjectIds));
		}
		return new ArrayList<>();
	}

	private void buildDateJ10003(List<Project> projectList,List<J1003> rowDataLists,String reportDateStr){
		Date reportDate = DateUtils.parseDateFromString(reportDateStr,DateUtils.DATE_FORMAT);
		log.info("上报日期reportDate={}",reportDate);
		for (Project project : projectList) {
			if (project.getChannelCode().equals(ChannelCodeEnum.KAOLA.getChanelCode())){
				continue;
			}

			final Date investEndTime = projectBorrowerPlanNewMapperExt.selectLastRefundDayByProjectId(project.getProjectId());
			if (investEndTime == null){
				log.info("investEndTime标的异常{},",project.getProjectId());
				continue;
			}
			List<ProjectInvestOrder> projectInvestOrderList = projectInvestOrderMapperExt.selectInvestedList(project.getProjectId());
			for (ProjectInvestOrder projectInvestOrder : projectInvestOrderList) {
				if (projectInvestOrder.getInvestType().equals(Byte.valueOf("2"))){//债转订单
                    log.info("债转订单{}",JSON.toJSONString(projectInvestOrder));
				}
				J1003 rowData = new J1003();
				rowData.setJ1003001(project.getProjectId().toString());
				rowData.setJ1003002(projectInvestOrder.getUserId());
				rowData.setJ1003003(projectInvestOrder.getInvestorName());
				rowData.setJ1003004("0");//身份证

				//如果是个人
				if (projectInvestOrder.getInvestorType().equals(Byte.valueOf("1"))){
					rowData.setJ1003005(privacyMasks.decryptPrivacy(projectInvestOrder.getInvestorIdCard()));
				}else {
					log.info("投资人是企业，证件类型是身份证，idCard传的企业法人身份证号userId={}",projectInvestOrder.getUserId());
					//如果是企业

					SimpleOrgInfo simpleOrgInfo = organizationDubboService.getByOrgId(projectInvestOrder.getUserId());
					rowData.setJ1003013(simpleOrgInfo.getRepresentative());//法人代表
					rowData.setJ1003005(privacyMasks.decryptPrivacy(simpleOrgInfo.getLegalPersonCertNumber()));
				}
				try {
					rowData.setJ1003006(userBasicInfoDubboService.getUserBasicInfo(projectInvestOrder.getUserId()).getMobileNo());
				}catch (Exception e){
					log.info("投资人手机号查询异常{}",projectInvestOrder.getUserId(),e);
				}
				rowData.setJ1003007(DateUtils.format(projectInvestOrder.getCreateTime(),DateUtils.SHOW_DATETIME_FORMAT));
				rowData.setJ1003008(projectInvestOrder.getAmount().toString());
				//如果是原始标，起始日取放款时间
				Date startTime = project.getFullSuccessTime();
				if (projectInvestOrder.getInvestType().equals(Byte.valueOf("2"))){//债转订单，直接取订单表FullSuccessTime
					startTime = projectInvestOrder.getFullSuccessTime() == null? projectInvestOrder.getCreateTime():projectInvestOrder.getFullSuccessTime();
				}
				rowData.setJ1003009(""+RepaymentUtil.getOverdueDay(startTime,investEndTime));
				rowData.setJ1003010(DateUtils.format(investEndTime,DateUtils.SHOW_DATE_FORMAT));

				rowData.setJ1003011(project.getBorrowRate().multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_EVEN).toString());//company_trades
				List<ProjectInvestorPlan> projectInvestorPlanList = projectInvestorPlanMapperExt.listProjectInvestorPlanNotReceived(projectInvestOrder.getId(), projectInvestOrder.getProjectId());//逾期超过4天
				BigDecimal capitalNotReceive = new BigDecimal("0.00");
				BigDecimal interestNotReceive = new BigDecimal("0.00");
				for (ProjectInvestorPlan investorPlan : projectInvestorPlanList) {
					capitalNotReceive = capitalNotReceive.add(investorPlan.getCapital().subtract(investorPlan.getReceivedCapital()));
					interestNotReceive = interestNotReceive.add(investorPlan.getInterest().subtract(investorPlan.getReceivedInterest()));
				}
				rowData.setJ1003012(capitalNotReceive.toString());
				rowData.setJ1003013(interestNotReceive.toString());
				//已结清或者已转让  记录结清日期
				if (projectInvestOrder.getEvolutionStatus().equals(ProjectInvestOrderEvolutionStatusEnum.ALL_BACKED.getValue())
						|| projectInvestOrder.getEvolutionStatus().equals(ProjectInvestOrderEvolutionStatusEnum.TRANSFERRED.getValue())){
					Date lastOverTimeFromPlan = projectInvestorPlanMapperExt.selectMaxOverTime(projectInvestOrder.getId());
					Date overTime = lastOverTimeFromPlan == null? projectInvestOrder.getUpdateTime() : lastOverTimeFromPlan;
					rowData.setJ1003014(DateUtils.format(overTime,DateUtils.SHOW_DATE_FORMAT));
				}else {
					rowData.setJ1003014("0000-00-00");
				}
				rowData.setJ1003015(projectInvestOrder.getPlatformUserNo());
				rowDataLists.add(rowData);
			}
		}
	}





	private void buildDateJ10004(List<Project> projectList, List<J1004> rowDataLists, String reportDateStr) {
		Date reportDate = DateUtils.parseDateFromString(reportDateStr,DateUtils.DATE_FORMAT);
		log.info("buildDateJ10004上报日期reportDate={}",reportDate);
		Set<String> setGuarantees = new HashSet<>();//收集担保公司user_id
		//guarantee_company_org_id指向担保公司user_id,org_id是推标机构ID
		projectList.forEach( p -> setGuarantees.add( p.getGuaranteeCompanyOrgId()));
		log.info("收集担保公司mapGuarantees={}", JSON.toJSONString(setGuarantees));
		Map<String,SimpleOrgInfo> userMaps = new HashMap<>();
		Map<String,AccountCompanyDTO> accountCompanyDTOMaps = new HashMap<>();
		for (String guaranteeCompanyOrgId : setGuarantees) {
			try {
				SimpleOrgInfo simpleOrgInfo = organizationDubboService.getByOrgId(guaranteeCompanyOrgId);
				AccountCompanyDTO accountCompanyDTO = accountCompanyDubboService.queryAccountCompanyByUserId(guaranteeCompanyOrgId);
				userMaps.put(guaranteeCompanyOrgId, simpleOrgInfo);
				accountCompanyDTOMaps.put(guaranteeCompanyOrgId,accountCompanyDTO);
			}catch (Exception e){
				log.error("据用户userId查询账户信息异常userId={}",guaranteeCompanyOrgId,e);
			}
		}
		log.info("担保公司信息userMaps{},accountCompanyDTOMaps{}",JSON.toJSONString(userMaps),JSON.toJSONString(accountCompanyDTOMaps));

		for (Project project : projectList) {
			if ( project.getChannelCode().equals(ChannelCodeEnum.KAOLA.getChanelCode()) ){
				continue;
			}
			if ( userMaps.get(project.getGuaranteeCompanyOrgId()) == null || accountCompanyDTOMaps.get(project.getGuaranteeCompanyOrgId()) == null ){
				log.info("担保机构{}不存在，标的{}异常",project.getGuaranteeCompanyOrgId(),project.getProjectId());
				continue;
			}
			BigDecimal capitalAmount = new BigDecimal("0.00");
			BigDecimal interestAmount = new BigDecimal("0.00");
			List<ProjectGuaranteePlan> projectGuaranteePlanList = projectGuaranteePlanMapperExt.selectListByProjectId(project.getProjectId());
			String latestGuaranteeDateStr = "0000-00-00";
			Date latestGuaranteeDate = null;
			if (!CollectionUtils.isEmpty(projectGuaranteePlanList)){
				for (ProjectGuaranteePlan guaranteePlan : projectGuaranteePlanList) {
					capitalAmount = capitalAmount.add(guaranteePlan.getCapital());
					interestAmount = interestAmount.add(guaranteePlan.getInterest());
					if (latestGuaranteeDate == null
							|| (latestGuaranteeDate.before(guaranteePlan.getCreateTime()))){
						latestGuaranteeDate = guaranteePlan.getCreateTime();
						latestGuaranteeDateStr = DateUtils.formatDate(latestGuaranteeDate,DateUtils.SHOW_DATE_FORMAT);
						log.info("标的号={}，latestGuaranteeDate={},latestGuaranteeDateStr={}",project.getProjectId(),latestGuaranteeDate,latestGuaranteeDateStr);
					}
				}
			}
			J1004 rowData = new J1004();
			rowData.setJ1004001(project.getProjectId().toString());
			rowData.setJ1004002(project.getGuaranteeCompanyOrgId());
			rowData.setJ1004003("3");//1-抵押；2-质押；3-保证；4-保险
			rowData.setJ1004004("1");//0-自然人;1-法人机构。

			rowData.setJ1004005(userMaps.get(project.getGuaranteeCompanyOrgId()).getOrganizationName());


			rowData.setJ1004006("4");//统一社会代码
			rowData.setJ1004007(userMaps.get(project.getGuaranteeCompanyOrgId()).getUnifiedSocialCreditCode());
			BigDecimal interest = projectBorrowerPlanDetailMapperExt.countTotalMoneyByProjectIdAndFeeType(project.getProjectId(),FeeTypeEnum.INTEREST.getValue());
			rowData.setJ1004008(project.getContractAmount().add(interest).toString());
			rowData.setJ1004009(null);
			rowData.setJ1004010(null);

			rowData.setJ1004011(capitalAmount.toString());//
			rowData.setJ1004012(interestAmount.toString());//
			rowData.setJ1004013(latestGuaranteeDateStr);
			rowData.setJ1004014(accountCompanyDTOMaps.get(project.getGuaranteeCompanyOrgId()).getAccountNo());
			rowDataLists.add(rowData);
		}

	}




	private Map<String,Object> getCountMap(String reportDateStr,ParamsDate paramsDate){
		Date reportDate = DateUtils.parseDateFromString(reportDateStr,DateUtils.DATE_FORMAT);
		Map<String, Object> countMap;
		if (reportDate.before(DateUtils.parseDateFromString("20181028",DateUtils.DATE_FORMAT))) {
			countMap = projectMapperExt.countFullProjectByDateRepaying(paramsDate.getStartDate(), paramsDate.getEndDate());
		}else {
			countMap = projectMapperExt.countFullProjectByDate(paramsDate.getStartDate(), paramsDate.getEndDate());
		}
		return countMap;
	}

	private List<Project> getProjectList(String reportDateStr,ParamsDate paramsDate,Integer startIndex,Integer pageSize){
		Date reportDate = DateUtils.parseDateFromString(reportDateStr,DateUtils.DATE_FORMAT);
		List<Project> projectList;
		if (reportDate.before(DateUtils.parseDateFromString("20181028",DateUtils.DATE_FORMAT))) {
			projectList = projectMapperExt.selectFullProjectByDateRepaying(paramsDate.getStartDate(), paramsDate.getEndDate(), startIndex, pageSize);
		}else {
			projectList = projectMapperExt.selectFullProjectByDate(paramsDate.getStartDate(), paramsDate.getEndDate(), startIndex, pageSize);
		}
		return projectList;
	}

	private ParamsDate getParamsDate(String reportDateStr){
		ParamsDate paramsDate = new ParamsDate();
		Date reportDate = DateUtils.parseDateFromString(reportDateStr,DateUtils.DATE_FORMAT);
		Date startDate;
		//10月28号之前直接取全量
		if (reportDate.before(DateUtils.parseDateFromString("20181028",DateUtils.DATE_FORMAT))){
			startDate = DateUtils.parseDateFromString("20140301",DateUtils.DATE_FORMAT);
		}else {
			startDate = reportDate;
		}
		Date endDate = new DateTime(reportDate).plusDays(1).toDate();//上报日期+1天
		paramsDate.setEndDate(endDate);
		paramsDate.setStartDate(startDate);
		return paramsDate;
	}

	public static void main(String[] args) {
		Set<Long> aeest = new HashSet<>();
		Set<Long> target = new HashSet<>();

		aeest.add(Long.valueOf("1"));
		aeest.add(Long.valueOf("2"));
		aeest.add(Long.valueOf("3"));

		target.add(Long.valueOf("3"));
		target.add(Long.valueOf("4"));
		target.add(Long.valueOf("5"));
		aeest.removeAll(target);
		System.out.println(aeest);
	}
}
